package cn.scu.ne04jdemo.controller;

import cn.hutool.core.date.DateUtil;
import cn.scu.ne04jdemo.entitiy.ScheOrderInfoEntity;
import cn.scu.ne04jdemo.entitiy.ScheOrderTaskInfoEntity;
import cn.scu.ne04jdemo.entitiy.ScheTaskDevMatchInfoEntity;
import cn.scu.ne04jdemo.service.ScheOrderInfoService;
import cn.scu.ne04jdemo.service.ScheOrderTaskInfoService;
import cn.scu.ne04jdemo.service.ScheTaskDevMatchInfoService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import okhttp3.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/sche/activate")
public class ScheActivateController {

    @Autowired
    private ScheOrderTaskInfoService scheOrderTaskInfoService;
    @Autowired
    private ScheOrderInfoService scheOrderInfoService;
    @Autowired
    private ScheTaskDevMatchInfoService scheTaskDevMatchInfoService;


    @GetMapping("/do")
    public ResponseEntity<IPage> doActivate() {
        List<JSONObject> orderList = scheOrderTaskInfoService.getScheActivateOrderInfo();
        List<JSONObject> devList = scheOrderTaskInfoService.getScheActivateDevInfo();
        Map<String, Integer> devindex = new HashMap<>();
        Map<String, Integer> orderindex = new HashMap<>();
        Map<String, Integer> taskindex = new HashMap<>();
        Set<String> ordertask = new HashSet<>();

        JSONObject jo = null;
        if(orderList != null && orderList.size() > 0 && devList != null && devList.size() > 0){
            Set<String> so = new HashSet<>();
            Set<String> st = new HashSet<>();
            int dlen = devList.size();
            for(JSONObject json : orderList){
                so.add(json.getString("orderId"));
                st.add(json.getString("prodTaskId"));
            }
            int olen = so.size();
            int tlen = st.size();
            int Processing_time[][][] = new int[olen][tlen][dlen];
            int Processing_cost[][][] = new int[olen][tlen][dlen];
            int Pre_relationship[][][] = new int[olen][tlen][dlen];
            int task_num[] = new int[olen];
            int tasksum = 0;

            // 初始化成本、时间、前置关系信息
            for(int i = 0 ; i < olen; i++){
                for(int u = 0; u < tlen; u++){
                    for(int v= 0; v < dlen; v++){
                        Processing_time[i][u][v] = -1;
                        Processing_cost[i][u][v] = -1;
                        Pre_relationship[i][u][v] = -1;
                    }
                }
            }

            for(int i = 0; i < devList.size(); i++){
                jo = devList.get(i);
                devindex.put(jo.getString("devId"), i);
            }
            int oi = 0;
            int ti = 0;
            String orderId = "";
            String taskId = "";
            String devId = "";
            for(JSONObject json : orderList){
                if(!StringUtils.equals(orderId, json.getString("orderId"))){
                    orderId = json.getString("orderId");
                    if(oi > 0) {
                        task_num[oi-1] = ti;
                        tasksum += ti;
                    }
                    orderindex.put(orderId, oi++);
                    ti = 0;
                }
                if(!StringUtils.equals(taskId, json.getString("prodTaskId")) || ti == 0){
                    taskId = json.getString("prodTaskId");
                    taskindex.put(taskId, ti);
                    ti++;
                }
                devId = json.getString("devId");
                Processing_time[oi-1][ti-1][devindex.get(devId)] = json.getInteger("processTime");
                Processing_cost[oi-1][ti-1][devindex.get(devId)] = 1;
            }
            task_num[oi-1] = ti;
            tasksum += ti;


            JSONObject params = new JSONObject();
            params.put("J_num", olen);
            params.put("M_num", devList.size());
            params.put("O_num", tasksum);
            params.put("Op_num", task_num);
            params.put("Processing_time", Processing_time);
            params.put("Processing_cost", Processing_cost);
            params.put("Pre_relationship", Pre_relationship);
            String scheResult = doRequest(params);
            if(StringUtils.isNotBlank(scheResult)){
                JSONObject scheResultJson = JSONObject.parseObject(scheResult);
                List<Integer> jCost = scheResultJson.getObject("Jobs_Cost", List.class);
                List<Integer> jEndTime = scheResultJson.getObject("Jobs_EndTime", List.class);
                List<Integer> jStartTime = scheResultJson.getObject("Jobs_StartTime", List.class);
                List<List<Integer>> tEndTime = scheResultJson.getObject("Tasks_EndTime", List.class);
                List<List<Integer>> tStartTime = scheResultJson.getObject("Tasks_StartTime", List.class);
                List<List<BigDecimal>> devMatch = scheResultJson.getObject("devMatch", List.class);
                Date date = new Date();

                //更新订单交货日期信息
                List<ScheOrderInfoEntity> soList = new ArrayList<>();
                List<ScheOrderTaskInfoEntity> stList = new ArrayList<>();
                int oidx = 0;
                int tidx = 0;
                int didx = 0;
                for(String key : orderindex.keySet()){
                    oidx = orderindex.get(key);
                    ScheOrderInfoEntity soie = new ScheOrderInfoEntity();
                    soie.setId(key);
                    soie.setScheDeliveryDate(timeAddHour(date, jEndTime.get(oidx)));
                    soie.setDeliveryDateAct(timeAddHour(date, jEndTime.get(oidx)));
                    soList.add(soie);
                    scheOrderInfoService.updateById(soie);
                }
//                scheOrderInfoService.updateBatchById(soList);

                int ordertasklen = 0;
                String orderTaskId = ""; //订单任务id
                for(JSONObject json : orderList){
                    ordertasklen = ordertask.size();
                    orderId = json.getString("orderId");
                    taskId =  json.getString("prodTaskId");
                    orderTaskId = json.getString("taskId");
                    ordertask.add(orderId + taskId);
                    if(ordertasklen + 1 == ordertask.size()){
                        ScheOrderTaskInfoEntity sotie = new ScheOrderTaskInfoEntity();
                        sotie.setOrderId(orderId);
                        sotie.setProdTaskId(taskId);
                        oidx = orderindex.get(orderId);
                        tidx = taskindex.get(taskId);

                        //更新任务开始结束日期
                        sotie.setStartTime(timeAddHour(date, tStartTime.get(oidx).get(tidx)));
                        sotie.setEndTime(timeAddHour(date, tEndTime.get(oidx).get(tidx)));
                        scheOrderTaskInfoService.update(sotie, new QueryWrapper<ScheOrderTaskInfoEntity>()
                                .eq("order_id", orderId)
                                .eq("prod_task_id", taskId));

                        //更新任务设备匹配信息
                        ScheTaskDevMatchInfoEntity stdmi = new ScheTaskDevMatchInfoEntity();
                        BigDecimal dev = devMatch.get(oidx).get(tidx);
                        stdmi.setOrderId(orderId);
                        stdmi.setTaskId(orderTaskId);
                        stdmi.setDevId(devList.get(dev.intValue()).getString("devId"));
                        stdmi.setScheStartTime(timeAddHour(date, tStartTime.get(oidx).get(tidx)));
                        stdmi.setScheEndTime(timeAddHour(date, tEndTime.get(oidx).get(tidx)));
                        scheTaskDevMatchInfoService.save(stdmi);
                    }
                }

            }
        }

        return ResponseEntity.ok(null);
    }

    private String doRequest(JSONObject params){
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(120, TimeUnit.SECONDS) // 连接超时时间
                .readTimeout(120, TimeUnit.SECONDS)    // 读取超时时间
                .build();

        String url = "http://47.96.146.116:8999/merge-arrays";

        // 构建 JSON 请求体
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        String jsonBody = params.toJSONString();
        RequestBody requestBody = RequestBody.create(JSON, jsonBody);
        // 构建请求
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        // 发起异步请求
        /*client.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // 处理响应
                if (response.isSuccessful()) {
                    String responseBody = response.body().string();
                    System.out.println("Response: " + responseBody);
                } else {
                    System.out.println("Request failed: " + response.code());
                }
            }

            @Override
            public void onFailure(Call call, IOException e) {
                // 处理失败
                e.printStackTrace();
            }
        });*/
        //发起同步请求
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String responseBody = response.body().string();
                System.out.println("Response: " + responseBody);
                return responseBody;
            } else {
                System.out.println("Request failed: " + response.code());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private LocalDateTime timeAddHour(Date date, int hour){

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        // 步骤3：使用Calendar对象的add方法加小时
        calendar.add(Calendar.HOUR_OF_DAY, hour);

        return DateUtil.toLocalDateTime(calendar.getTime());
    }

   /* public static void main(String[] args) {
        int len = 5;
        int test[][][] = new int[len][][];
        for(int i = 0 ; i < 5; i++){
            for(int u = 0; u < i+2; u++){
                for(int v= 0; v < 3; v++){
                    test[i][u][v] = 1;
                }
            }
        }
    }*/

}
